using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Windows;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using System.Windows.Media;

public class AeroHelper
    {
    public class DwmApi
    {
        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern bool DwmIsCompositionEnabled();

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmGetColorizationColor(
            out int pcrColorization,
            [MarshalAs(UnmanagedType.Bool)]out bool pfOpaqueBlend);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmEnableComposition(bool bEnable);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern IntPtr DwmRegisterThumbnail(IntPtr dest, IntPtr source);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmUpdateThumbnailProperties(IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size);

        [StructLayout(LayoutKind.Sequential)]
        public class DWM_THUMBNAIL_PROPERTIES
        {
            public uint dwFlags;
            public RECT rcDestination;
            public RECT rcSource;
            public byte opacity;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fVisible;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fSourceClientAreaOnly;

            public const uint DWM_TNP_RECTDESTINATION = 0x00000001;
            public const uint DWM_TNP_RECTSOURCE = 0x00000002;
            public const uint DWM_TNP_OPACITY = 0x00000004;
            public const uint DWM_TNP_VISIBLE = 0x00000008;
            public const uint DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;
        }

        [StructLayout(LayoutKind.Sequential)]
        public class MARGINS
        {
            public int cxLeftWidth, cxRightWidth, cyTopHeight, cyBottomHeight;

            public MARGINS(int left, int top, int right, int bottom)
            {
                cxLeftWidth = left;
                cyTopHeight = top;
                cxRightWidth = right;
                cyBottomHeight = bottom;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public class DWM_BLURBEHIND
        {
            public uint dwFlags;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fEnable;
            public IntPtr hRegionBlur;
            [MarshalAs(UnmanagedType.Bool)]
            public bool fTransitionOnMaximized;

            public const uint DWM_BB_ENABLE = 0x00000001;
            public const uint DWM_BB_BLURREGION = 0x00000002;
            public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left, top, right, bottom;

            public RECT(int left, int top, int right, int bottom)
            {
                this.left = left;
                this.top = top;
                this.right = right;
                this.bottom = bottom;
            }
        }
        /// <summary>
        /// Do Not Draw The Caption (Text)
        /// </summary>
        public static uint WTNCA_NODRAWCAPTION = 0x00000001;
        /// <summary>
        /// Do Not Draw the Icon
        /// </summary>
        public static uint WTNCA_NODRAWICON = 0x00000002;
        /// <summary>
        /// Do Not Show the System Menu
        /// </summary>
        public static uint WTNCA_NOSYSMENU = 0x00000004;
        /// <summary>
        /// Do Not Mirror the Question mark Symbol
        /// </summary>
        public static uint WTNCA_NOMIRRORHELP = 0x00000008;

        /// <summary>
        /// The Options of What Attributes to Add/Remove
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct WTA_OPTIONS
        {
            public uint dwFlags;
            public uint dwMask;
        }

        /// <summary>
        /// What Type of Attributes? (Only One is Currently Defined)
        /// </summary>
        public enum WindowThemeAttributeType
        {
            WTA_NONCLIENT = 1,
        };
    }
    public static bool ExtendGlassFrame(Window window, Thickness margin)
        {
            try
            {
                if (!DwmApi.DwmIsCompositionEnabled())
                    return false;

                IntPtr hwnd = new WindowInteropHelper(window).Handle;
                if (hwnd == IntPtr.Zero)
                    throw new InvalidOperationException("The Window must be shown before extending glass.");

                // Set the background to transparent from both the WPF and Win32 perspectives
                window.Background = Brushes.Transparent;
                HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;

                DwmApi.MARGINS margins = new DwmApi.MARGINS((int)margin.Left, (int)margin.Top, (int)margin.Right, (int)margin.Bottom);
                DwmApi.DwmExtendFrameIntoClientArea(hwnd, margins);
            }
            catch (Exception e)
            {
            }

            return true;
        }


    /// <summary>
    /// Set The Window's Theme Attributes
    /// </summary>
    /// <param name="hWnd">The Handle to the Window</param>
    /// <param name="wtype">What Type of Attributes</param>
    /// <param name="attributes">The Attributes to Add/Remove</param>
    /// <param name="size">The Size of the Attributes Struct</param>
    /// <returns>If The Call Was Successful or Not</returns>
    [DllImport("UxTheme.dll")]
    public static extern int SetWindowThemeAttribute(IntPtr hWnd, DwmApi.WindowThemeAttributeType wtype, ref DwmApi.WTA_OPTIONS attributes, uint size);

    // Win32 API needed
    [DllImport("user32")]
    private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);
    [DllImport("user32")]
    private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);

    // A delegate that matches Win32 WNDPROC:
    private delegate int Win32WndProc(IntPtr hWnd, int Msg, int wParam, int lParam);

    // from winuser.h:
    private const int GWL_WNDPROC = -4;
    private const int WM_LBUTTONDOWN = 0x0201;

    // program variables
    private IntPtr oldWndProc = IntPtr.Zero;
    private Win32WndProc newWndProc = null;

    public void SubclassHWnd(IntPtr hWnd)
    {
        // hWnd is the window you want to subclass..., create a new 
        // delegate for the new wndproc
        newWndProc = new Win32WndProc(DWMWndProc);
        // subclass
        oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc);
    }
    [DllImport("dwmapi.dll")]
    public static extern int DwmDefWindowProc(IntPtr hwnd, ushort msg, long wParam, long lParam, out int plResult);

    public const int WM_NCCALCSIZE = 131;
    // this is the new wndproc, just show a messagebox on left button down:
    private int DWMWndProc(IntPtr hWnd, int Msg, int wParam, int lParam)
    {
        int lResult = 0;
        DwmDefWindowProc(hWnd, (ushort)Msg, (long)wParam, (long)lParam,out lResult);
        switch (Msg)
        {
            case WM_NCCALCSIZE:
                if (wParam != 0)
                {
                    return 0;
                }
                break;
        }

        return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam);
    }

}

